def wrap_puzzle_text(text_with_breaks, line_length):
    lines = []
    current_line = []
    i = 0
    text = text_with_breaks.replace('\n', ' ')

    while i < len(text):
        current_char = text[i]
        lookahead = text[i:i+3]

        if len(current_line) == 0 and current_char == ' ':
            i += 1
        elif len(current_line) < line_length - 4:
            current_line.append({"original_index": i, "char": current_char})
            i += 1
        else:
            if current_char == " ":
                lines.append(current_line)
                current_line = []
                i += 1
            elif current_char in ",.!?;:'\"":
                if len(lookahead) > 1 and lookahead[1] == " ":
                    current_line.append({"original_index": i, "char": current_char})
                    lines.append(current_line)
                    current_line = []
                    i += 1
                else:
                    current_line.append({"original_index": i, "char": current_char})
                    current_line.append({"char": "-"})
                    lines.append(current_line)
                    current_line = []
                    i += 1
            elif len(lookahead) == 3 and all(c.isalpha() for c in lookahead):
                current_line.append({"original_index": i, "char": lookahead[0]})
                current_line.append({"original_index": i+1, "char": lookahead[1]})
                current_line.append({"char": "-"})
                lines.append(current_line)

                if (lookahead[2] != ' '):
                    current_line = [{"original_index": i+2, "char": lookahead[2]}]
                else:
                    current_line = []
                i += 3
            elif len(lookahead) > 1 and lookahead[1] == " ":
                current_line.append({"original_index": i, "char": current_char})
                lines.append(current_line)
                current_line = []
                i += 1
            else:
                current_line.append({"char": "-"})
                lines.append(current_line)
                current_line = [{"original_index": i, "char": current_char}]
                i += 1

    if current_line:
        lines.append(current_line)

    return lines

def wrap_text(input_string, wrap_width):
    words = input_string.split()
    lines = []
    current_line = ""

    for word in words:
        # If the word itself is longer than the wrap width, put it on its own line
        if len(word) > wrap_width:
            if len(current_line) > 0:
                lines.append(current_line)
                current_line = ""
            lines.append(word)
        # If adding the word would exceed the wrap width, start a new line
        elif len(current_line) + len(word) + (1 if len(current_line) > 0 else 0) > wrap_width:
            lines.append(current_line)
            current_line = word
        else:
            current_line += (" " if len(current_line) > 0 else "") + word

    if len(current_line) > 0:
        lines.append(current_line)

    return lines
